
/**
 * @FileName:ZipTools.java
 * @Description: TODO
 * @Copyright: All rights Reserved, Designed By [amado] Copyright(C) 2010-2018
 * @Company: 米特娱乐乐园
 * @author:amado
 * @version: V1.0 
 * @Create:2018年5月4日 上午10:25:09
 *
 * Modification  History:
 * Date         Author        Version        Discription
 * -----------------------------------------------------------------------------------
 * 2018年5月4日      amado          1.0             1.0
 * Why & What is modified: <修改原因描述>
 */
package com.amado.course38zipInputStream;
 
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
 
 
 
/**
 * @类名称：ZipTools
 * @类描述：采用zip压缩文件
 * @创建人：amado
 * @创建时间：2018年5月4日 上午10:25:09
 * @版权：Copyright@2018.All Rights Reserved
 * @version v1.0
 */
public class ZipUtil {
	/**
	 * @创建日期：2018年5月4日 下午1:37:22
	 * @作者： amado
	 * @描述：压缩多个文件的情况
	 * @Title: zip
	 * @param fileList
	 * @param zipFile
	 * @throws Exception
	 */
	public static void zipFiles(List<File> fileList,File zipFile) throws Exception{
		System.out.println("zipFiles待压缩文件："+zipFile.getAbsolutePath());
		if(fileList != null){
			if(zipFile.exists()){//压缩文件已经存在，则只能单个添加
				for(File file:fileList){
					zip(zipFile,file);
				}
			}else{//不存在则新建
				// 创建zip输出流
				ZipOutputStream zipOutStream = new ZipOutputStream(new FileOutputStream(zipFile), Charset.forName("UTF-8"));
				// 创建缓冲输出流
				BufferedOutputStream bufferOutStream = new BufferedOutputStream(zipOutStream);
				for(File file:fileList){
					zipFile(file,zipOutStream,bufferOutStream);
				}
				//最后关闭输出流
				bufferOutStream.close();
				zipOutStream.close();
			}
			
		}
	}
	/**
	 * @创建日期：2018年5月4日 下午1:44:55
	 * @作者： amado
	 * @描述：执行文件压缩
	 * @Title: zipFile
	 * @param file
	 * @param zipOutStream
	 * @param bufferOutStream
	 * @throws IOException
	 */
	private static void zipFile(File file,ZipOutputStream zipOutStream,BufferedOutputStream bufferOutStream) throws IOException{
		// 创建压缩文件实体
		ZipEntry entry = new ZipEntry(file.getName());
		// 添加实体
		zipOutStream.putNextEntry(entry);
		// 创建输入流
		BufferedInputStream bufferInputStream = new BufferedInputStream(new FileInputStream(file));
		write(bufferInputStream, bufferOutStream);
		zipOutStream.closeEntry();
	}
	/**
	 * @创建日期：2018年5月4日 下午1:37:01
	 * @作者： amado
	 * @描述：压缩单个文件
	 * @Title: zip
	 * @param zipFile
	 * @param sourceFile
	 * @throws Exception
	 */
	public static void zip(File zipFile, File sourceFile) throws Exception {
		System.out.println("待压缩文件："+zipFile.getAbsolutePath());
		if (zipFile.exists()) {// 添加到已经存在的压缩文件中
			
			File tempFile=new File(zipFile.getAbsolutePath()+".tmp");
			// 创建zip输出流
			ZipOutputStream zipOutStream = new ZipOutputStream(new FileOutputStream(tempFile), Charset.forName("UTF-8"));
			// 创建缓冲输出流
			BufferedOutputStream bufferOutStream = new BufferedOutputStream(zipOutStream);
			ZipFile zipOutFile = new ZipFile(zipFile);
			
			Enumeration<? extends ZipEntry> entries = zipOutFile.entries();
			while (entries.hasMoreElements()) {
				ZipEntry entry = entries.nextElement();
				System.out.println("copy: " + entry.getName());
				zipOutStream.putNextEntry(entry);
				if (!entry.isDirectory()) {
					write(zipOutFile.getInputStream(entry), bufferOutStream);
				}
				zipOutStream.closeEntry();
			}
			zipOutFile.close();//记得关闭zip文件，否则后面无法删除原始文件
			ZipEntry entry = new ZipEntry(sourceFile.getName());
			// 添加实体
			zipOutStream.putNextEntry(entry);
			BufferedInputStream bufferInputStream = new BufferedInputStream(new FileInputStream(sourceFile));
			write(bufferInputStream, bufferOutStream);
			//最后关闭输出流
			bufferOutStream.close();
			zipOutStream.close();
			boolean flag=zipFile.delete();
			if(flag){
			tempFile.renameTo(zipFile);
			}else{
				System.out.println("删除文件失败。");
			}
		} else {// 新创建压缩文件
			// 创建zip输出流
			ZipOutputStream zipOutStream = new ZipOutputStream(new FileOutputStream(zipFile), Charset.forName("UTF-8"));
			// 创建缓冲输出流
			BufferedOutputStream bufferOutStream = new BufferedOutputStream(zipOutStream);
			// 创建压缩文件实体
			ZipEntry entry = new ZipEntry(sourceFile.getName());
			// 添加实体
			zipOutStream.putNextEntry(entry);
			// 创建输入流
			BufferedInputStream bufferInputStream = new BufferedInputStream(new FileInputStream(sourceFile));
			write(bufferInputStream, bufferOutStream);
			//最后关闭输出流
			bufferOutStream.close();
			zipOutStream.close();
		}
		
	}
	/**
	 * @创建日期：2018年5月4日 下午2:09:37
	 * @作者： amado
	 * @描述：读写zip文件
	 * @Title: write
	 * @param inputStream
	 * @param outStream
	 * @throws IOException
	 */
    private static void write(InputStream inputStream,OutputStream outStream) throws IOException{
    	byte[] data=new byte[4096];
    	int length=0;
    	while((length=inputStream.read(data)) != -1){
    		outStream.write(data,0,length);
    	}
    	outStream.flush();//刷新输出流
    	inputStream.close();//关闭输入流
    }
    
    /**
     * @创建日期：2018年5月4日 下午3:07:55
     * @作者： amado
     * @描述：压缩指定目录下所有文件
     * @Title: zipDirectory
     * @param dirFile
     * @param zipFile
     * @throws IOException 
     */
    public static void zipDirectory(File dirFile,File zipFile) throws IOException{
    	if(dirFile != null && dirFile.isDirectory()){
    		if(zipFile == null){
    			zipFile=new File(dirFile.getAbsolutePath()+".zip");
    		}
    		String dirName=dirFile.getName()+File.separator;
    		// 创建zip输出流
			ZipOutputStream zipOutStream = new ZipOutputStream(new FileOutputStream(zipFile), Charset.forName("UTF-8"));
			// 创建缓冲输出流
			BufferedOutputStream bufferOutStream = new BufferedOutputStream(zipOutStream);
			dealDirFile( dirFile,dirName,bufferOutStream,zipOutStream);
			
			//最后关闭输出流
			bufferOutStream.close();
			zipOutStream.close();
    	}else{
    		System.out.println("["+dirFile.getName()+"]不是一个文件夹,或者不存在。");
    	}
    }
    /**
     * @创建日期：2018年5月4日 下午4:38:46
     * @作者： amado
     * @描述：处理目录文件
     * @Title: dealDirFile
     * @param dirFile
     * @param parentDir
     * @param bufferOutStream
     * @param zipOutStream
     * @throws IOException
     */
    private static void dealDirFile(File dirFile,String parentDir, BufferedOutputStream bufferOutStream, ZipOutputStream zipOutStream) throws IOException{
    	File[] fileList=dirFile.listFiles();
    	for(File file:fileList){
    		if(file.isFile()){
    			// 创建压缩文件实体
    			ZipEntry entry = new ZipEntry(parentDir+file.getName());
    			// 添加实体
    			zipOutStream.putNextEntry(entry);
    			// 创建输入流
    			BufferedInputStream bufferInputStream = new BufferedInputStream(new FileInputStream(file));
    			write(bufferInputStream, bufferOutStream);
    		}else{
    			dealDirFile(file,  parentDir+file.getName()+File.separator,  bufferOutStream,  zipOutStream);
    		}
    	}
    }
    /**
     * @创建日期：2018年5月4日 下午3:22:11
     * @作者： amado
     * @描述：重载zipDirectory
     * @Title: zipDirectory
     * @param dirPath
     * @param zipPath
     * @throws IOException
     */
    public static void zipDirectory(String dirPath,String zipPath) throws IOException{
    	if(zipPath==null || "".equals(zipPath)){
    		zipDirectory(new File(dirPath),null);
    	}else{
    		zipDirectory(new File(dirPath),new File(zipPath));
    	}
    }
   //------------------------------------------------米特华丽的分割线----------------------------------------------------------------------------------------
   public static void unzip(File zipFile) throws IOException {
	   unzip(zipFile,null);
   }
    /**
     * @创建日期：2018年5月4日 下午4:00:41
     * @作者： amado
     * @描述：解压文件
     * @Title: unzip
     * @param zipFile 要解压的zip文件
     * @param destDir 解压的目录
     * @throws IOException 
     */
	public static void unzip(File zipFile, File destDir) throws IOException {
		//解压目录为null地，默认解压到zip所有的文件夹
		if (destDir == null) {
			destDir = new File(zipFile.getParent());
		}
		ZipFile zipOutFile = new ZipFile(zipFile,Charset.forName("UTF-8"));
		Enumeration<? extends ZipEntry> entries = zipOutFile.entries();
		while (entries.hasMoreElements()) {
			ZipEntry entry = entries.nextElement();
			if(entry.isDirectory()){
				File tempFile = new File(destDir.getAbsolutePath()+File.separator+entry.getName());
				if (!tempFile.exists()) {
					tempFile.mkdirs();
				}
			}else{
				File tempFile=new File(destDir.getAbsolutePath()+File.separator+entry.getName());
				checkParentDir(tempFile);
				FileOutputStream fileOutStream=new FileOutputStream(tempFile);
				BufferedOutputStream bufferOutStream = new BufferedOutputStream(fileOutStream);
				write(zipOutFile.getInputStream(entry),bufferOutStream);
				bufferOutStream.close();
				fileOutStream.close();
			}
		}
		zipOutFile.close();//记得关闭zip文件
	}
	
	/**
	 * @创建日期：2018年5月4日 下午4:37:41
	 * @作者： amado
	 * @描述：验证父目录是否存在，否则创建
	 * @Title: checkParentDir
	 * @param file
	 */
	private static void checkParentDir(File file){
		if(!file.getParentFile().exists()){
			file.getParentFile().mkdirs();
		}
	}
	
}
